unit math.config;

interface
uses
  Windows, SysUtils, Generics.Collections, sci.config, sci.log, sci.module,
  math.global, IniFiles, math.category;

var
  rootPath, modPath, confFile, cateConfFile: string;

type
  TMathConf = record
    core: string;
    modules: TList<String>;
    nrCategories: integer;
  end;

var
  mathConf: TMathConf;

procedure config_init;
procedure module_init;
procedure category_init(langfile: TIniFile);

implementation

procedure config_init;
var
  cl: TConfList;
begin
  rootPath := ExtractFilePath(ParamStr(0));
  modPath := rootPath + 'modules\';
  confFile := rootPath + 'config\mathengine\main.conf';
  cateConfFile := rootPath + 'config\mathengine\categories.conf';

  cl := NewConfList;
  AddToConfList(cl, NewConf('core'));
  AddToConfList(cl, NewConf('modules'));
  AddToConfList(cl, NewConf('nr_categories'));

  log(mathLog, 'Parsing config file...');
  ParseConf(cl, confFile);

  mathConf.core := STRVALUE(cl, 'core');
  mathConf.modules := TList<String>.Create;
  strlist(cl, 'modules', mathConf.modules);
  mathConf.nrCategories := INTVALUE(cl, 'nr_categories');
end;

procedure module_init;
var
  i: integer;
begin
  log(mathLog, 'Loading modules...');
  for i := 0 to mathConf.modules.Count - 1 do
  begin
    LoadModule(modPath + mathConf.modules[i]);
  end;
end;

procedure category_init(langfile: TIniFile);
var
  i, j: integer;
  cl: TConfList;
  subhandles: TList<String>;
  corelib: THandle;
  init: procedure; stdcall;
begin
  log(mathLog, 'Initializing categories...');

  corelib := LoadLibrary(PChar(mathConf.core));

  init := GetProcAddress(corelib, Pchar('init_core'));
  init;

  cl := NewConfList;
  for i := 1 to mathConf.nrCategories do
  begin
    AddToConfList(cl, NewConf('category' + IntToStr(i) + '_nrsub'));
    AddToConfList(cl, NewConf('category' + IntToStr(i) + '_handles'));
  end;

  log(mathLog, 'Parsing category config file...');
  ParseConf(cl, CateConfFile);

  for i := 0 to mathConf.nrCategories - 1 do
  begin
    categories[i].name := langfile.ReadString('Categories', 'category' + IntToStr(i)
                                                  , 'Default');
    subhandles := TList<String>.Create;
    strlist(cl, 'category' + IntToStr(i + 1) + '_handles', subhandles);
    for j := 0 to INTVALUE(cl, 'category' + IntToStr(i + 1) + '_nrsub') - 1 do
    begin
      categories[i].subcates[j].caption := langfile.ReadString('Category' + IntToStr(i),
                                     'subcategory' + IntToStr(j), 'Default');
      categories[i].subcates[j].btnCaption := langfile.ReadString('Category' + IntToStr(i),
                                     'btncaption' + IntToStr(j), 'Default');
      categories[i].subcates[j].func := GetProcAddress(corelib, PChar(subhandles[j]));
      if @categories[i].subcates[j].func = nil then error('No such handle: ' +
                                                            subhandles[j]);
      log(mathLog, categories[i].subcates[j].caption )
    end;
  end;
end;


end.
